home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
comm
/
net
/
amitcp_ups10.lha
/
ups.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-10
|
13KB
|
689 lines
#ifndef lint
static char RCSid[] = "$Header: QD:ups/ups2/RCS/ups.c,v 1.8 1986/12/11 15:58:18 scooter Exp alph $";
#endif
/*
* ups - user interface to the package delivery system
*
* usage: ups user@host file1 file2 ...
*
* $Author: scooter $
* $Revision: 1.8 $
* $Date: 1986/12/11 15:58:18 $
*
* $Log: ups.c,v $
* Revision 1.8 86/12/11 15:58:18 scooter
* Added alias expansion code which allows ups to follow /usr/lib/aliases.
*
* Revision 1.7 86/09/19 18:53:15 scooter
* Added -i option for mail specification
*
* Revision 1.6 86/09/18 15:19:45 scooter
* More fixes to the '.' problam
*
* Revision 1.5 86/09/17 09:43:38 scooter
* Added code to do automatic renaming of "." files for delivery to
* avoid the "cannot delete" problem
*
* Revision 1.4 85/08/21 22:27:45 scooter
* Release revision: added more complete RCS headers.
*
*/
#ifdef amigados
#include "sys.h"
#endif
#include <stdio.h>
#include <pwd.h>
#include <ndbm.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <netdb.h>
#include <ctype.h>
#ifdef amigados
#include "ups_protos.h"
#endif
#define LS "/bin/ls"
struct passwd *getpwuid();
FILE *fopen();
int rem;
int qflg = 0;
int iflg = 0;
int on = 1;
char buffer[BUFSIZ*5];
char mbuffer[BUFSIZ*4];
struct user_list {
char *u_user;
char *u_host;
struct user_list *u_next;
};
#ifdef KR
main(argc, argv)
char **argv;
int argc;
#else
int main(int argc, char **argv)
#endif
{
char myhost[BUFSIZ];
int file;
int ret;
#ifdef amigados
char *user,*host,*tmp;
#else
char *user,*host,*tmp,*rindex(),*index();
#endif
struct passwd *mypwent;
#ifdef amigados
struct user_list *u_top, *alias_expand();
struct user_list dummy_user;
#else
struct user_list *u_list,*u_top, *alias_expand();
#endif
#ifdef amigados
if(1)
{
char *env;
env = getenv("HOSTNAME");
if(!env)
{
fprintf(stderr, "HOSTNAME not set\n");
exit(1);
}
strncpy(myhost, env, BUFSIZ);
env = getenv("USERNAME");
if(!env)
{
fprintf(stderr, "USERNAME not set\n");
exit(1);
}
mypwent = malloc(sizeof(struct passwd));
memset(mypwent, 0, sizeof(struct passwd));
mypwent->pw_passwd = strdup("");
mypwent->pw_shell = strdup("");
mypwent->pw_name = strdup(env);
mypwent->pw_gecos = strdup("Amiga OS Power User");
}
#else
gethostname(myhost,BUFSIZ);
if( (mypwent = getpwuid(getuid())) == NULL )
{
fprintf(stderr,"ups: who are you?\n");
exit(1);
}
#endif
argv++;
argc--;
while (argc && *argv[0] == '-')
{
char c;
switch (c = argv[0][1])
{
case 'q':
qflg++;
break;
case 'i':
iflg++;
break;
default:
fprintf(stderr,"ups: unknown option %c\n",c);
}
argv++;
argc--;
}
if (argc <= 1 || qflg)
upsread(mypwent);
if (argc < 2)
{
fprintf(stderr,"usage: ups user@host file1 file2 ...\n");
exit(0);
}
/*
* Get the name of the destination user and host
*/
user = argv[0];
host = rindex(user,'@');
fprintf(stderr, "user = %s\n", user);
#ifndef ALIASES
if (host == NULL)
host = myhost;
else
*host++ = '\0';
u_top = &dummy_user;
dummy_user.u_next = 0;
dummy_user.u_user = user;
dummy_user.u_host = host;
#else
if (host != NULL)
*host++ = '\0';
u_top = alias_expand(user,host,myhost);
#endif /* ALIASES */
#ifdef DEBUG
printf("Here we are again\n");
#endif
if (iflg)
upsgetmsg(mbuffer);
else
mbuffer[0] = '\0';
while(u_top != NULL)
{
#ifdef DEBUG
printf("Connecting to %s for user %s\n",u_top->u_host,u_top->u_user);
#endif
rem = upsconnect(u_top->u_host); /* Connect to the server */
/*
* Send the to name, from name, and our name
*/
tmp = index(mypwent->pw_gecos,',');
if (tmp)
*tmp = '\0';
sprintf(buffer, "%s\n%s\n%s\n%s", u_top->u_user,
mypwent->pw_name, mypwent->pw_gecos,mbuffer);
#ifdef DEBUG
printf("Sending: %s\n",buffer);
fflush(stdout);
#endif /* DEBUG */
write(rem, buffer, strlen(buffer)+1);
ret = read(rem, buffer, BUFSIZ);
if (buffer[0])
problem(1);
for (file = 1 ; file < argc ; file++)
{
#ifdef DEBUG
printf("Sending file: %s\n",argv[file]);
#endif /* DEBUG */
sendfile(argv[file]);
}
sprintf(buffer, "-Done-");
write(rem, buffer, strlen(buffer)+1);
read(rem, buffer, BUFSIZ); /* get result */
if (buffer[0]) /* problem? */
problem(1); /* yes, go handle it */
close(rem);
u_top = u_top->u_next;
}
}
upsconnect(host)
char *host;
{
struct hostent *hp;
struct servent *sp;
struct sockaddr_in sin;
int s;
hp = gethostbyname(host);
if (hp == NULL) {
static struct hostent def;
static struct in_addr defaddr;
static char namebuf[128];
#ifndef amigados
int inet_addr();
#endif
defaddr.s_addr = inet_addr(host);
if (defaddr.s_addr == -1) {
printf("unknown host: %s\n", host);
exit(1);
}
strcpy(namebuf, host);
def.h_name = namebuf;
def.h_addr = (char *)&defaddr;
def.h_length = sizeof (struct in_addr);
def.h_addrtype = AF_INET;
def.h_aliases = 0;
hp = &def;
}
sp = getservbyname("ups", "tcp");
if (sp == 0) {
fprintf(stderr,"tcp/ups: unknown service\n");
exit(1);
}
sin.sin_family = hp->h_addrtype;
bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
sin.sin_port = sp->s_port;
s = socket(hp->h_addrtype, SOCK_STREAM, 0);
if (s < 0) {
fflush(stderr);
perror("ups (socket)");
exit(1);
}
setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,&on,sizeof(on));
#ifdef DEBUG
setsockopt(s,SOL_SOCKET,SO_DEBUG,&on,sizeof(on));
#endif /* DEBUG */
if (connect(s, (char *)&sin, sizeof (sin)) < 0) {
fflush(stderr);
perror("ups (connect)");
close(s);
exit(1);
}
return(s);
}
sendfile(file)
char *file;
{
struct stat fstatus;
int loc,n;
char *tmp,*fname;
if ( (loc = open(file,O_RDONLY)) <= 0 ) {
perror("ups (open)");
return(1);
}
if (fstat(loc, &fstatus)) {
perror("ups (fstat)");
return(1);
}
if ((fstatus.st_mode&S_IFMT) != S_IFREG) {
switch (fstatus.st_mode&S_IFMT)
{
case S_IFDIR:
tmp = "directory";
break;
#ifdef S_IFCHR
case S_IFCHR:
tmp = "character device";
break;
case S_IFBLK:
tmp = "block device";
break;
#endif
#ifdef S_IFLNK
case S_IFLNK:
tmp = "symbolic link";
break;
#endif
#ifdef S_IFSOCK
case S_IFSOCK:
tmp = "socket";
break;
#endif
}
fprintf(stderr,
"ups: %s is a %s, only regular files may be sent\n",
file,tmp);
fflush(stderr);
return(1);
}
/*
* Send the file name
*/
/*
* First strip off the directory path
*/
sprintf(buffer,"%s",file);
#ifndef amigados
tmp = rindex(buffer,'/');
if (tmp)
*tmp++ = '\0';
else
tmp = buffer;
#else
tmp = rindex(buffer,'/');
if (tmp)
*tmp++ = '\0';
else
{
tmp = rindex(buffer,':');
if (tmp)
*tmp++ = '\0';
else
tmp = buffer;
}
#endif
fname = tmp;
if (*tmp == '.')
{
while ( (*tmp == '.') && (*tmp != '\0') )tmp++;
fprintf(stdout,
"WARNING: file %s has been renamed to %s for delivery\n",
fname,tmp);
}
write(rem, tmp, strlen(tmp)+1);
read(rem, buffer, BUFSIZ);
if (buffer[0]) /* problem */
{
problem(0);
return(1);
}
/*
* Send the file size in bytes
*/
sprintf(buffer, "%d",fstatus.st_size);
write(rem, buffer, strlen(buffer)+1);
read(rem, buffer, BUFSIZ);
if (buffer[0]) /* problem */
{
problem(0);
return(1);
}
/*
* Send the file
*/
while (n = read(loc, buffer, BUFSIZ))
write(rem, buffer, n);
close(loc);
read(rem, buffer, BUFSIZ); /* get result */
if (buffer[0]) /* problem */
{
problem(0);
return(1);
}
#ifndef amigados
sprintf(buffer, "%u", fstatus.st_mode);
#else /* use unix modes for transmission*/
{
int unix_mode=0, ami_mode;
ami_mode = fstatus.st_mode;
if(ami_mode & 8)
unix_mode |= 0400;
if(ami_mode & 5)
unix_mode |= 0200;
if(ami_mode & 2)
unix_mode |= 0100;
sprintf(buffer, "%u", unix_mode);
}
#endif
write(rem, buffer, strlen(buffer)+1);
read(rem, buffer, BUFSIZ); /* get result */
if (buffer[0]) /* problem */
{
problem(0);
return(1);
}
return(0);
}
upsread(mypwent)
struct passwd *mypwent;
{
#ifndef amigados
union wait status;
int pid;
char c;
#endif
char line[BUFSIZ],*tmp;
#ifdef amigados
strmfp(buffer,UPSDIR,mypwent->pw_name);
#else
sprintf(buffer,"%s/%s",UPSDIR,mypwent->pw_name);
#endif
if (qflg)
{
if (!access(buffer,F_OK)) {
fprintf(stderr,
"You have ups files awaiting you (type ups to accept delivery)\n");
}
exit(0);
}
if (access(buffer,F_OK)) {
fprintf(stderr,"Nothing waiting in ups\n");
exit(0);
}
fprintf(stdout,"\nYou have the following files awaiting delivery:\n\n");
#ifdef amigados
{
char lbuf[BUFSIZ];
sprintf(lbuf, "list %s", buffer);
system(lbuf);
}
#else
if (pid = vfork())
{
wait(&status);
} else {
execl(LS,"ls","-C",buffer,(char *)0);
perror("ups (exec)");
return(0);
}
#endif
fprintf(stdout,"\n");
fprintf(stdout,
"Do you wish to accept delivery in your\n");
#ifdef amigados
fprintf(stdout,
"current directory (%s)? ",
getcwd(line, BUFSIZ));
#else
fprintf(stdout,
"current directory (%s)? ",
getwd(line));
#endif
getinp:
if (fgets(line,BUFSIZ,stdin) == NULL) {
fprintf(stdout,"\n");
exit(0);
}
tmp = &line[0];
while (isspace(*tmp)) tmp++;
switch (*tmp) {
case 'y':
case 'Y':
#ifndef amigados
sprintf(line,"mv -i %s/* . ; rmdir %s",buffer,buffer);
system(line);
#else
sprintf(line,"copy %s/#? \"\"",buffer);
if(!system(line))
{
sprintf(line,"c:delete %s ALL FORCE",buffer);
system(line);
}
#endif
exit(0);
case 'n':
case 'N':
exit(0);
default:
fprintf(stdout,"Please answer 'yes' or 'no': ");
goto getinp;
}
}
/*
* problem() is called when the install demon process return a non-zero reply.
* This usually means something recognizable went wrong and we should expect
* a reason to follow. Read in the reason, output it on the terminal and die.
*/
problem(die)
int die;
{
char buf[BUFSIZ]; /* place to read into */
if (read(rem, buf, BUFSIZ) > 0) /* if we have something */
fprintf(stderr, "ups: %s", buf);
if (die) {
close(rem); /* close network channel */
exit(1);
}
}
int
upsgetmsg(mailbuffer)
char *mailbuffer;
{
int done = 0;
fprintf(stdout,
"Enter your message followed by '.<RETURN>' or a <CTRL>D:\n");
while (!done)
{
fprintf(stdout,"> ");
if (gets(mailbuffer) == NULL)
{
fprintf(stdout,"\n");
done++;
} else if ( (*mailbuffer == '.') && (*(mailbuffer+1) == '\0'))
{
done++;
*mailbuffer = '\0';
} else {
while(*mailbuffer != '\0')
mailbuffer++;
*mailbuffer++ = '\n';
*mailbuffer = '\0';
}
}
fprintf(stdout,"[EOT]\n");
}
#ifdef ALIASES
struct user_list *
alias_expand(user,host,myhost)
char *user,*host,*myhost;
{
#ifndef amigados
char *malloc();
#endif
DBM *dp;
datum key,content;
struct user_list *list,*top,*alloc_list();
char *cp,*tp,*hp;
list = top = (struct user_list *)NULL;
if (host != NULL)
return(alloc_list(user,host));
dp = dbm_open("/usr/lib/aliases", O_RDONLY, 0644);
if (dp == NULL) {
if(host == NULL)
return(alloc_list(user, myhost));
else
return(alloc_list(user, host));
}
key.dptr = user;
key.dsize = strlen(user) + 1;
content = dbm_fetch(dp,key);
if (content.dptr == NULL)
return(alloc_list(user,myhost));
cp = content.dptr;
while (cp != NULL)
{
tp = cp;
cp = index(cp,',');
if (cp != NULL)
*cp++ = '\0';
if (index(tp,'!')) {
fprintf(stderr,
"ups: WARNING: cannot alias %s to %s (no ups over uucp)\n",
user,hp);
continue;
} else if(index(tp,'|')) {
fprintf(stderr,
"ups: WARNING: cannot alias %s to %s (no shells allowed)\n",
user,hp);
continue;
}
hp = tp;
hp = index(tp,'@');
if (hp == NULL)
hp = myhost;
else
*hp++ = '\0';
if (top == NULL)
top = list = alloc_list(tp,hp);
else
{
list->u_next = alloc_list(tp,hp);
list = list->u_next;
}
}
return(top);
}
#endif
struct user_list *alloc_list(user,host)
char *user,*host;
{
#ifndef amigados
char *malloc();
#endif
struct user_list *list;
list = (struct user_list *)malloc(sizeof(struct user_list));
list->u_user = malloc(strlen(user) + 1);
list->u_host = malloc(strlen(host) + 1);
strcpy(list->u_user,user);
strcpy(list->u_host,host);
list->u_next = (struct user_list *)NULL;
return(list);
}